/*
 * nrf24.c
 *
 *  Created on: Dec 3, 2020
 *      Author: zhen
 */

#include "nrf24.h"

NRF_HandleTypeDef hnrf;

uint8_t TX_ADDRESS[5] = {0xb0, 0xb1, 0xb2, 0xb3, 0x01};

uint8_t NRF_ReadStatus(void)
{
	uint8_t readBuffer[2];
	uint8_t writeBuffer[2];

	writeBuffer[0] = 0xff;
	writeBuffer[1] = 0;

	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_RESET);
	HAL_SPI_TransmitReceive(&hspi1, writeBuffer, readBuffer, 2, HAL_MAX_DELAY);
	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_SET);
	return readBuffer[0];
}

uint8_t NRF_ReadReg(uint8_t regAddr)
{
	uint8_t readBuffer[2];
	uint8_t writeBuffer[2];

	writeBuffer[0] = regAddr;
	writeBuffer[1] = 0;

	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_RESET);
	HAL_SPI_TransmitReceive(&hspi1, writeBuffer, readBuffer, 2, HAL_MAX_DELAY);
	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_SET);
	return readBuffer[1];
}

uint8_t NRF_WriteReg(uint8_t regAddr, uint8_t value)
{
	uint8_t readBuffer[2];
	uint8_t writeBuffer[2];

	writeBuffer[0] = regAddr;
	writeBuffer[1] = value;

	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_RESET);
	HAL_SPI_TransmitReceive(&hspi1, writeBuffer, readBuffer, 2, HAL_MAX_DELAY);
	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_SET);

	return readBuffer[0];
}

uint8_t NRF_WriteRegs(uint8_t regAddr, uint8_t *value, uint8_t len)
{
	uint8_t readBuffer;

	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_RESET);
	HAL_SPI_TransmitReceive(&hspi1, &regAddr, &readBuffer, 1, HAL_MAX_DELAY);
	HAL_SPI_Transmit(&hspi1, value, len, HAL_MAX_DELAY);
	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_SET);
	return readBuffer;
}

uint8_t NRF_ReadRegs(uint8_t regAddr, uint8_t *value, uint8_t len)
{
	uint8_t readBuffer;

	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_RESET);
	HAL_SPI_TransmitReceive(&hspi1, &regAddr, &readBuffer, 1, HAL_MAX_DELAY);
	HAL_SPI_Receive(&hspi1, value, len, HAL_MAX_DELAY);
	HAL_GPIO_WritePin(NRF24_CS_GPIO_Port, NRF24_CS_Pin, GPIO_PIN_SET);

	return readBuffer;
}

void NRF_Init(void)
{
	hnrf.nrfMode = NRF_RX_MODE;
	hnrf.nrfAA = 1;
}

void NRF_RX_Mode(void)
{
	HAL_GPIO_WritePin(NRF24_CE_GPIO_Port, NRF24_CE_Pin, GPIO_PIN_RESET);
	NRF_WriteRegs(WRITE_REG_NRF24L01 + RX_ADDR_P0, TX_ADDRESS, 5);
	NRF_WriteReg(WRITE_REG_NRF24L01 + RX_PW_P0, 32);

	NRF_WriteReg(WRITE_REG_NRF24L01 + EN_AA, 0x3f);               // 使能接收通道0自动应答
	NRF_WriteReg(WRITE_REG_NRF24L01 + EN_RXADDR, 0x3f);           // 使能接收通道0
	NRF_WriteReg(WRITE_REG_NRF24L01 + RF_CH, 40);                 // 选择射频通道0x40

	NRF_WriteReg(WRITE_REG_NRF24L01 + RF_SETUP, 0x06);            // 数据传输率1Mbps，发射功率0dBm，低噪声放大器增益
	NRF_WriteReg(WRITE_REG_NRF24L01 + CONFIG, 0x0f);              // CRC使能，16位CRC校验，上电，接收模式

	HAL_GPIO_WritePin(NRF24_CE_GPIO_Port, NRF24_CE_Pin, GPIO_PIN_SET);
}

void NRF_TX_Mode(void)
{
	HAL_GPIO_WritePin(NRF24_CE_GPIO_Port, NRF24_CE_Pin, GPIO_PIN_RESET);

	NRF_WriteRegs(WRITE_REG_NRF24L01 + TX_ADDR, TX_ADDRESS, 5);     // 写入发送地址
	NRF_WriteRegs(WRITE_REG_NRF24L01 + RX_ADDR_P0, TX_ADDRESS, 5);  // 为了应答接收设备，接收通道0地址和发送地址相同

	NRF_WriteReg(WRITE_REG_NRF24L01 + EN_AA, 0x3f);       // 使能接收通道0自动应答
	NRF_WriteReg(WRITE_REG_NRF24L01 + EN_RXADDR, 0x3f);   // 使能接收通道0
	NRF_WriteReg(WRITE_REG_NRF24L01 + SETUP_RETR, 0x35);  // 自动重发延时等待1000us+86us，自动重发5次
	NRF_WriteReg(WRITE_REG_NRF24L01 + RF_CH, 40);         // 选择射频通道0x40
	NRF_WriteReg(WRITE_REG_NRF24L01 + RF_SETUP, 0x06);    // 数据传输率1Mbps，发射功率0dBm，低噪声放大器增益
	NRF_WriteReg(WRITE_REG_NRF24L01 + RX_PW_P0, 32);  // 接收通道0选择和发送通道相同有效数据宽度
	NRF_WriteReg(WRITE_REG_NRF24L01 + CONFIG, 0x0c);      // CRC使能，16位CRC校验，不上电

	HAL_GPIO_WritePin(NRF24_CE_GPIO_Port, NRF24_CE_Pin, GPIO_PIN_SET);
}

void NRF_TX_Packet(uint8_t *txBuffer)
{
	HAL_GPIO_WritePin(NRF24_CE_GPIO_Port,NRF24_CE_Pin, GPIO_PIN_RESET);

	NRF_WriteRegs(WR_TX_PLOAD, txBuffer, 32);							//装载数据
	NRF_WriteReg(WRITE_REG_NRF24L01 + CONFIG, 0x0e);      // CRC使能，16位CRC校验，不上电

	HAL_GPIO_WritePin(NRF24_CE_GPIO_Port, NRF24_CE_Pin, GPIO_PIN_SET);
}

int NRF_SendData(uint8_t *txBuffer)
{
	uint8_t status = 0;
	NRF_TX_Mode();
	NRF_TX_Packet(txBuffer);
	while(HAL_GPIO_ReadPin(NRF24_IRQ_GPIO_Port, NRF24_IRQ_Pin) == GPIO_PIN_SET);

	HAL_GPIO_WritePin(NRF24_CE_GPIO_Port, NRF24_CE_Pin, GPIO_PIN_RESET);
	status = NRF_ReadReg(STATUS);
//	status = NRF_ReadStatus();

	if(status & TX_DS)
	{
		NRF_WriteReg(WRITE_REG_NRF24L01 + STATUS, TX_DS);
		return 0;
	}
	else
	{
		NRF_WriteReg(WRITE_REG_NRF24L01 + STATUS, MAX_RT);
		return -1;
	}
}

int NRF_ReceiveData(uint8_t *rxBuffer)
{
	uint8_t status = 0;
	NRF_RX_Mode();

	while(HAL_GPIO_ReadPin(NRF24_IRQ_GPIO_Port, NRF24_IRQ_Pin) == GPIO_PIN_SET);

	HAL_GPIO_WritePin(NRF24_CE_GPIO_Port, NRF24_CE_Pin, GPIO_PIN_RESET);
	status = NRF_ReadReg(STATUS);

	if(status & RX_DR)
	{
		NRF_ReadRegs(RD_RX_PLOAD, rxBuffer, 32);
		NRF_WriteReg(WRITE_REG_NRF24L01 + STATUS, RX_DR);
		return 0;
	}
	return -1;
}
